#include <am.h>
#include <klib.h>
#include <klib-macros.h>

#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
static unsigned long int next = 1;

int rand(void) {
  // RAND_MAX assumed to be 32767
  next = next * 1103515245 + 12345;
  return (unsigned int)(next/65536) % 32768;
}

void srand(unsigned int seed) {
  next = seed;
}

int abs(int x) {
  return (x < 0 ? -x : x);
}

int atoi(const char* nptr) {
  int x = 0;
  while (*nptr == ' ') { nptr ++; }
  while (*nptr >= '0' && *nptr <= '9') {
    x = x * 10 + *nptr - '0';
    nptr ++;
  }
  return x;
}

void itoa(long n, char *buf){
	int i = 0; 
	if (n<10){
		buf[0] = n +'0';
		buf[1] = '\0';
//		putch('\n');
//		putch('i');
//		putch(buf[0]);
		return;
	}
	itoa(n / 10, buf);
	for (int l =0;buf[l]!='\0';l++)
		i=l+1;	
	buf[i] = (n % 10) + '0';
	buf[i+1] = '\0';
//	putch(buf[i]);


}

void itoahex(long n, char *buf){
	int i = 0; 
	if (n<16){
		if(n<10){
		 buf[0] = n +'0';
		 buf[1] = '\0';
		}
		else{
		 buf[0] = n - 10 +'a';
		 buf[1] = '\0';
		}
//		putch('\n');
//		putch('i');
//		putch(buf[0]);
		return;
	}
	itoahex(n / 16, buf);
	for (int l =0;buf[l]!='\0';l++)
		i=l+1;	
	if(n % 16 <10){
		 buf[i] = (n % 16)  +'0';
		 buf[i+1] = '\0';
		}
	else{
		 buf[i] = (n % 16) - 10 +'a';
		 buf[i+1] = '\0';
	}
//	putch(buf[i]);


}
static char *hbrk;
//= heap.start;
static int i = 1;

void *malloc(size_t size) {
  // On native, malloc() will be called during initializaion of C runtime.
  // Therefore do not call panic() here, else it will yield a dead recursion:
  //   panic() -> putchar() -> (glibc) -> malloc() -> panic()
#if !(defined(__ISA_NATIVE__) && defined(__NATIVE_USE_KLIB__))
  size  = (size_t)ROUNDUP(size, 8);
  if(i == 1)
  {
  	hbrk = (void *)ROUNDUP(heap.start, 8);
//	putch('1');
//	putch('\n');
	i++;
  }
  char *old = hbrk;
  hbrk += size;
  //putch('2');
  assert((uintptr_t)heap.start <= (uintptr_t)hbrk && (uintptr_t)hbrk < (uintptr_t)heap.end);
  for (uint64_t *p = (uint64_t *)old; p != (uint64_t *)hbrk; p ++) {
    *p = 0;
  }
  assert((uintptr_t)hbrk - (uintptr_t)heap.start >= 0);
  return old;
//    	panic("Not implemented");
#endif
  return NULL;
}

void free(void *ptr) {
}

#endif
